package org.seanye.com.junitrunnerui.junit;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import junit.framework.TestCase;

import org.seanye.com.junitrunnerui.util.JarUtil;

/**
 * Find test cases in Junit format into a jar file.
 * 
 * @author seany1
 * 
 */
@SuppressWarnings("unchecked")
public class JavaFinder implements IFinder {

	private static final String JUNIT_FRAMEWORK_TEST_SUITE = "junit.framework.TestSuite";
	private static final String JUNIT_FRAMEWORK_TEST_CASE = "junit.framework.TestCase";
	private final String jarPath;
	private final String[] dependenceJars;

	public JavaFinder(String jarPath, String[] dependenceJars) {
		super();
		this.jarPath = jarPath;
		this.dependenceJars = dependenceJars;
	}

	public String getJarPath() {
		return jarPath;
	}

	public String[] getDependenceJars() {
		return dependenceJars;
	}

	public List<Junit3Test> find() {
		try {
			List<Junit3Test> result = new ArrayList<Junit3Test>();
			List<Class<?>> klasses = JarUtil.loadKlasses(getJarPath(),
					getDependenceJars());
			List<Class<TestCase>> junitTests = new ArrayList<Class<TestCase>>(
					klasses.size());
			List<Class<TestCase>> junitSuites = new ArrayList<Class<TestCase>>(
					klasses.size());
			for (Class<?> klass : klasses) {
				Class<?> superclass = klass.getSuperclass();
				internal: while (superclass != null) {
					if (JUNIT_FRAMEWORK_TEST_CASE.equals(superclass
							.getCanonicalName())) {
						junitTests.add((Class<TestCase>) klass);
						break internal;
					} else if (JUNIT_FRAMEWORK_TEST_SUITE.equals(superclass
							.getCanonicalName())) {
						junitSuites.add((Class<TestCase>) klass);
						break internal;
					}
					superclass = superclass.getSuperclass();
				}
			}
			// Find test instance(Just for junit 3)
			for (Class<TestCase> testcase : junitTests) {
				Junit3Test e = new Junit3Test(testcase);
				if (e.isValid()) {
					result.add(e);
				}
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return Collections.EMPTY_LIST;
	}

}
